home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / pd4990a.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  4KB  |  224 lines

  1. /*
  2.  *    Emulation for the NEC PD4990A.
  3.  *
  4.  *    The PD4990A is a serial I/O Calendar & Clock IC used in the
  5.  *      NEO GEO and probably a couple of other machines.
  6.  */
  7.  
  8. #include "driver.h"
  9. #include "machine/pd4990a.h"
  10.  
  11. /* Set the data in the chip to Monday 09/09/73 00:00:00     */
  12. /* If you ever read this Leejanne, you know what I mean :-) */
  13. int seconds=0x00;        /* BCD */
  14. int minutes=0x00;        /* BCD */
  15. int hours=0x00;        /* BCD */
  16. int days=0x09;        /* BCD */
  17. int month=9;        /* Hexadecimal form */
  18. int year=0x73;        /* BCD */
  19. int weekday=1;        /* BCD */
  20.  
  21. int retraces=0;            /* Assumes 60 retraces a second */
  22. int coinflip=0;            /* Pulses a bit in order to simulate */
  23.                     /* test output */
  24. int outputbit=0;
  25. int bitno=0;
  26.  
  27. void addretrace (void) {
  28.     coinflip ^= 1;
  29.     retraces++;
  30.     if (retraces == 60) {
  31.         retraces = 0;
  32.         seconds++;
  33.         if ((seconds & 0x0f) == 10) {
  34.             seconds &= 0xf0;
  35.             seconds += 0x10;
  36.             if ( seconds == 0x60) {
  37.                 seconds = 0;
  38.                 minutes++;
  39.                 if ( (minutes & 0x0f) == 10) {
  40.                     minutes &= 0xf0;
  41.                     minutes += 0x10;
  42.                     if (minutes == 0x60) {
  43.                         minutes = 0;
  44.                         hours++;
  45.                         if ( (hours & 0x0f) == 10 ){
  46.                             hours &= 0xf0;
  47.                             hours += 0x10;
  48.                         }
  49.                         if (hours == 0x24) {
  50.                             hours = 0;
  51.                             increment_day();
  52.                         }
  53.                     }
  54.                 }
  55.             }
  56.         }
  57.     }
  58. }
  59.  
  60. void    increment_day(void)
  61. {
  62.     int    real_year;
  63.  
  64.     days++;
  65.     if ((days & 0x0f) == 10)
  66.     {
  67.         days &= 0xf0;
  68.         days += 0x10;
  69.     }
  70.  
  71.     weekday++;
  72.     if (weekday==7)
  73.         weekday=0;
  74.  
  75.     switch(month)
  76.     {
  77.     case    1:
  78.     case    3:
  79.     case    5:
  80.     case    7:
  81.     case    8:
  82.     case    10:
  83.     case    12:
  84.         if (days==0x32)
  85.         {
  86.             days=1;
  87.             increment_month();
  88.         }
  89.         break;
  90.     case    2:
  91.         real_year = (year>>4)*10 + (year&0xf);
  92.         if (real_year%4)    /* There are some rare exceptions, but I don't care ... */
  93.         {
  94.             if (days==0x29)
  95.             {
  96.                 days=1;
  97.                 increment_month();
  98.             }
  99.         }
  100.         else
  101.         {
  102.             if (days==0x30)
  103.             {
  104.                 days=1;
  105.                 increment_month();
  106.             }
  107.         }
  108.         break;
  109.     case    4:
  110.     case    6:
  111.     case    9:
  112.     case    11:
  113.         if (days==0x31)
  114.         {
  115.             days=1;
  116.             increment_month();
  117.         }
  118.         break;
  119.     }
  120. }
  121.  
  122. void    increment_month(void)
  123. {
  124.     month++;
  125.     if (month==13) {
  126.         month=1;
  127.         year++;
  128.         if ((year & 0x0f) == 10) {
  129.             year &= 0xf0;
  130.             year += 0x10;
  131.         }
  132.         if (year == 0xA0)        /* Happy new year 2000 !!! */
  133.             year = 0;
  134.     }
  135. }
  136.  
  137. int read_4990_testbit(void) {
  138.     return (coinflip);
  139. }
  140.  
  141. int read_4990_databit(void)
  142. {
  143.     return (outputbit);
  144. }
  145.  
  146. WRITE_HANDLER( write_4990_control_w )
  147. {
  148.  
  149.     data &= 0xff;
  150.  
  151.     switch (data) {
  152.         case 0x00:    /* Load Register */
  153.                 switch(bitno) {
  154.                     case 0x00:
  155.                     case 0x01:
  156.                     case 0x02:
  157.                     case 0x03:
  158.                     case 0x04:
  159.                     case 0x05:
  160.                     case 0x06:
  161.                     case 0x07: outputbit=(seconds >> bitno) & 0x01;
  162.                            break;
  163.                     case 0x08:
  164.                     case 0x09:
  165.                     case 0x0a:
  166.                     case 0x0b:
  167.                     case 0x0c:
  168.                     case 0x0d:
  169.                     case 0x0e:
  170.                     case 0x0f: outputbit=(minutes >> (bitno-8)) & 0x01;
  171.                            break;
  172.                     case 0x10:
  173.                     case 0x11:
  174.                     case 0x12:
  175.                     case 0x13:
  176.                     case 0x14:
  177.                     case 0x15:
  178.                     case 0x16:
  179.                     case 0x17: outputbit=(hours >> (bitno-16)) & 0x01;
  180.                            break;
  181.                     case 0x18:
  182.                     case 0x19:
  183.                     case 0x1a:
  184.                     case 0x1b:
  185.                     case 0x1c:
  186.                     case 0x1d:
  187.                     case 0x1e:
  188.                     case 0x1f: outputbit=(days >> (bitno-24)) & 0x01;
  189.                            break;
  190.                     case 0x20:
  191.                     case 0x21:
  192.                     case 0x22:
  193.                     case 0x23: outputbit=(weekday >> (bitno-32)) & 0x01;
  194.                            break;
  195.                     case 0x24:
  196.                     case 0x25:
  197.                     case 0x26:
  198.                     case 0x27: outputbit=(month >> (bitno-36)) & 0x01;
  199.                            break;
  200.                     case 0x28:
  201.                     case 0x29:
  202.                     case 0x2a:
  203.                     case 0x2b:
  204.                     case 0x2c:
  205.                     case 0x2d:
  206.                     case 0x2e:
  207.                     case 0x2f: outputbit=(year >> (bitno-40)) & 0x01;
  208.                            break;
  209.  
  210.                 }
  211.                 break;
  212.  
  213.         case 0x04:    /* Start afresh with shifting */
  214.                 bitno=0;
  215.                 break;
  216.  
  217.         case 0x02:    /* shift one position */
  218.                 bitno++;
  219.  
  220.         default:    /* Unhandled value */
  221.                 break;
  222.     }
  223. }
  224.